from pathlib import Path
import json
import matplotlib.pyplot as plt
import numpy as np

# 定义文件路径并读取文件内容
input_path = Path("trace_analysis.log")
contents = input_path.read_text().splitlines()

# 定义一个空列表
trace_logs = []

# 过滤出包含"static_multistream"字段的行
for line in contents:
    if "static_multistream" in line:
        trace_logs.append(line)

# for i in range(5):
#     print(trace_logs[i])

## 提取出所需数据
# 定义一个空字典
frame_data = {}

for trace_log in trace_logs:
    trace_list = trace_log.split('|')
    frame_id = trace_list[1].split(':')[1]
    process, status, time1 = trace_list[4].split(':')
    time1 = int(time1)
    if process == 'ProcessA' and status == 'start':
        frame_data[frame_id] = {}
        frame_data[frame_id]['startA'] = time1
    if process == 'ProcessA' and status == 'end':
        frame_data[frame_id]['endA'] = time1
    if process == 'ProcessB' and status == 'start':
        frame_data[frame_id]['startB'] = time1
    if process == 'ProcessB' and status == 'end':
        frame_data[frame_id]['endB'] = time1
# print(frame_data)

# 计算各工序的耗时
# 计算每一帧的ProcessA和ProcessB所花费的平均时间
work_A = []
work_B = []
for key, value in frame_data.items():
    if 'endA' in value and 'startA' in value:
        work_A.append(value['endA'] - value['startA'])
    if 'endB' in value and 'startB' in value:
        work_B.append(value['endB'] - value['startB'])
average_processA_time = np.mean(work_A)
average_processB_time = np.mean(work_B)
print(average_processA_time, average_processB_time)

# 计算ProcessA和ProcessB的P99耗时和P90耗时
# 将数据与帧ID结合并排序
frame_id1 = []
for id in frame_data.keys():
    frame_id1.append(id)
# print(frame_id1)

# 将数据与帧ID结合并排序
sorted_processA = sorted(zip(work_A, frame_id1))
sorted_processB = sorted(zip(work_B, frame_id1))

# 计算分位数索引
def get_percentile_index(data_length, percentile):
    return int(np.ceil(percentile / 100.0 * data_length)) - 1

p99_processA = get_percentile_index(len(sorted_processA), 99)
p90_processA = get_percentile_index(len(sorted_processA), 90)
p99_processB = get_percentile_index(len(sorted_processB), 99)
p90_processB = get_percentile_index(len(sorted_processB), 90)

# 获取分位数对应的时间和帧ID
time_99_processA, frame_99_processA = sorted_processA[p99_processA]
time_90_processA, frame_90_processA = sorted_processA[p90_processA]
time_99_processB, frame_99_processB = sorted_processB[p99_processB]
time_90_processB, frame_90_processB = sorted_processB[p90_processB]


# 打印结果
print(f"平均每帧ProcessA时间: {average_processA_time:.4f} ms")
print(f"平均每帧ProcessB时间: {average_processB_time:.4f} ms")
print(f"ProcessA时间的99%分位数: {time_99_processA:.4f} ms")
print(f"ProcessA时间的90%分位数: {time_90_processA:.4f} ms")
print(f"ProcessB时间的99%分位数: {time_99_processB:.4f} ms")
print(f"ProcessB时间的90%分位数: {time_90_processB:.4f} ms")


## 系统平均吞吐量
# 计算最后一帧的结束与第一帧的开始所花费的时间
total_time = int(frame_data[sorted(frame_id1)[-1]]['endB']) - int(frame_data[sorted(frame_id1)[0]]['startA']) / 1000
# 有效处理帧数数量
total_frame_count = len(frame_id1)
# 计算系统吞吐量
system_throughput = total_frame_count / total_time

# 打印结果
print(f"系统吞吐量：{system_throughput:.4f} frame/s")

## 平均帧
every_frame_time = []
for key, value in frame_data.items():
    if 'endA' in value and 'startA' in value and 'endB' in value and 'startB' in value:
        every_frame_time.append(value['endB'] - value['startA'])

avg_frame_time = np.mean(every_frame_time)
print(f"平均帧：{avg_frame_time:.4f} ms")

# 存储结果
results = {
    "ProcessA": {
        "平均每帧ProcessA时间": average_processA_time,
        "99_percentile": {
            "value": time_99_processA,
            "frame_id": frame_99_processA
        },
        "90_percentile": {
            "value": time_90_processA,
            "frame_id": frame_90_processA
        }
    },
    "ProcessB": {
        "平均每帧ProcessB时间": average_processB_time,
        "99_percentile": {
            "value": time_99_processB,
            "frame_id": frame_99_processB
        },
        "90_percentile": {
            "value": time_90_processB,
            "frame_id": frame_90_processB
        }
    },
    "系统吞吐量": system_throughput,
    "平均帧": avg_frame_time
}

## 保存结果
result_path = Path('result.json')
with result_path.open('w', encoding='utf-8') as f:
    json.dump(results, f, ensure_ascii=False, indent=4)

# 提取数据
frame_id2 = []
for id2, value1 in frame_data.items():
    if 'endA' in value1 and 'startA' in value1 and 'endB' in value1 and 'startB' in value1:
        frame_id2.append(int(id2))


processA_starts = []
processA_ends = []
processB_starts = []
processB_ends = []
for info in frame_data.values():
    if 'endA' in info and 'startA' in info and 'endB' in info and 'startB' in info:
        processA_starts.append(info['startA'])
        processA_ends.append(info['endA'])
        processB_starts.append(info['startB'])
        processB_ends.append(info['endB'])


# 创建绘图
fig, ax = plt.subplots(figsize=(10, 6))

frame_id3 = frame_id2[0:100]
# 绘制ProcessA的时间段
for idx, frame_id in enumerate(frame_id3):
    ax.plot([processA_starts[idx], processA_ends[idx]], [frame_id, frame_id], color='blue', label='ProcessA' if idx == 0 else "")

# 绘制ProcessB的时间段
for idx, frame_id in enumerate(frame_id3):
    ax.plot([processB_starts[idx], processB_ends[idx]], [frame_id, frame_id], color='red', label='ProcessB' if idx == 0 else "")

# 添加图例
ax.legend()

# 设置标签和标题
ax.set_xlabel('ms')
ax.set_ylabel('Frame ID')
ax.set_title('ProcessA and ProcessB Scheduling sequence diagram')

# 显示图形
plt.show()


